<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Userfiles;
use App\Models\Userfolders;
use Illuminate\Http\Request;

class UserfilesController extends Controller
{
    public function __construct()
    {
        $this->middleware('admin');
    }

    public function getIndex()
    {
        return view('admin/userfiles/index');
    }

    public function getPageRows(Request $request)
    {
        $user_id = session('token')['user_id'];

        $f_id = intval($request->input('f_id'));
        $page = toLimitLng($request->input('page'), 1);
        $limit = toLimitLng($request->input('limit'), 1);
        $offset = ($page - 1) * $limit;

        $data['folder'] = Userfolders::find($f_id);
        $data['folder_path'] = $this->getFolderPath($f_id);

        $fold_cnt = Userfolders::where('user_id', $user_id)->where('f_id', $f_id)->count();
        $file_cnt = Userfiles::where('user_id', $user_id)->where('folder_id', $f_id)->count();

        $fold_pages = ceil($fold_cnt / $limit);
        $total_rows = $fold_cnt + $file_cnt;

        $data['page'] = $page;
        $data['total_rows'] = $total_rows;
        $data['page_count'] = ceil($total_rows / $limit);

        $folder_rows = Userfolders::where('user_id', $user_id)->where('f_id', $f_id)->orderBy('sort', 'ASC')->skip($offset)->take($limit)->get();
        $data['folder_rows'] = $folder_rows;

        $file_rows = [];
        $residue = $limit - count($folder_rows);
        if ($residue > 0) {
            $offset = toLimitLng(($page - 1) * $limit - $fold_cnt);
            $raw = Userfiles::select('id', 'title', 'file_size', 'created_at');
            $raw->where('user_id', $user_id)->where('folder_id', $f_id);
            $file_rows = $raw->orderBy('title', 'ASC')->skip($offset)->take($residue)->get();
        }
        $data['file_rows'] = $file_rows;
        return $this->response($data);
    }

    private function getFolderPath($id, $ids = [])
    {
        array_push($ids, $id);
        $row = Userfolders::find($id);
        if (empty($row)) {
            return Userfolders::wherein('id', $ids)->get();
        } else {
            array_push($ids, $row->f_id);
            return $this->getFolderPath($row->f_id, $ids);
        }
    }

    public function postAddFolder(Request $request)
    {
        $user_id = session('token')['user_id'];
        $f_id = intval($request->input('f_id'));
        $name = safe($request->input('name'));

        $rows = Userfolders::select('name')->where('user_id', $user_id)->where('f_id', $f_id)->get();
        $name = $this->getNewName(array_values(array_dot($rows->toArray())), $name);
        $sort = Userfolders::where(['user_id' => $user_id, 'f_id' => $f_id])->max('sort') + 10;

        $row = new Userfolders;
        $row->user_id = $user_id;
        $row->f_id = $f_id;
        $row->sort = $sort;
        $row->name = $name;
        $row->save();

        return $this->response($row);
    }

    public function postRenFolder(Request $request)
    {
        $user_id = session('token')['user_id'];
        $id = intval($request->input('id'));
        $name = safe($request->input('name'));
        if (empty($name)) {
            return $this->error('无效的文件夹');
        }
        $row = Userfolders::where('user_id', $user_id)->find($id);
        if (empty($row)) {
            return $this->error('无效的文件夹');
        }
        if ($name == $row->name) {
            return $this->response($row);
        }
        $f_id = $row['f_id'];
        $rows = Userfolders::select('name')->where(['user_id' => $user_id, 'f_id' => $f_id])->get();
        $name = $this->getNewName(array_values(array_dot($rows->toArray())), $name);
        $row->name = $name;
        if ($row->save()) {
            return $this->response($row);
        }
        return $this->error('操作失败');
    }

    private function getNewName($arr, $name, $n = 1)
    {
        if (in_array($name, $arr)) {
            if (preg_match("/(.+)\(\d+\)$/i", $name, $matches)) {
                $new_name = $matches[1] . '(' . $n . ')';
            } else {
                $new_name = $name . '(' . $n . ')';
            }
            if (in_array($new_name, $arr)) {
                return $this->getNewName($arr, $name, ++$n);
            }
            return $new_name;
        }
        return $name;
    }

    public function postRemoveFolder(Request $request)
    {
        $user_id = session('token')['user_id'];
        $id = intval($request->input('id'));
        $row = Userfolders::where('user_id', $user_id)->find($id);
        if (empty($row)) {
            return $this->error('无效的文件夹');
        }
        $f_id = $row->f_id;

        $cnt = Userfolders::where('f_id', $id)->count();
        if ($cnt > 0) {
            return $this->error('请先删除此文件夹下的所有子文件夹');
        }
        if ($row->delete()) {
            Userfiles::where('folder_id', $id)->update(['folder_id' => $f_id]);
            return $this->response($id);
        }
        return $this->error('操作失败');
    }

    public function getFolderZtree()
    {
        $data = [['id' => 0, 'name' => '全部文件', 'open' => true]];
        $user_id = session('token')['user_id'];
        $query = Userfolders::where('user_id', $user_id);
        $rows = $query->orderBy('f_id', 'ASC')->orderBy('sort', 'ASC')->get();
        foreach ($rows as $row) {
            array_push($data, [
                'id' => $row->id,
                'pId' => $row->f_id,
                'sort' => $row->sort,
                'name' => $row->name,
            ]);
        }
        return $this->response($data);
    }

    public function postChangeSortByZtree(Request $request)
    {
        $source_id = intval($request->input('id'));
        $target_id = intval($request->input('targetId'));
        $move_type = strval($request->input('moveType')); //inner, prev, next

        $source = Userfolders::find($source_id);
        $target = Userfolders::find($target_id);

        switch ($move_type) {
            case 'prev':
                if ($source->sort > $target->sort) {
                    $query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
                    $query->whereBetween('sort', [$target->sort, $source->sort])->increment('sort', 10);
                    $query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
                    $query->where('id', $source_id)->update(['sort' => $target->sort]);
                } else {
                    $query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
                    $query->whereBetween('sort', [$source->sort, $target->sort - 10])->decrement('sort', 10);
                    $query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
                    $query->where('id', $source_id)->update(['sort' => $target->sort - 10]);
                }
                break;
            case 'next':
                if ($source->sort > $target->sort) {
                    $query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
                    $query->whereBetween('sort', [$target->sort + 10, $source->sort])->increment('sort', 10);
                    $query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
                    $query->where('id', $source_id)->update(['sort' => $target->sort + 10]);
                } else {
                    $query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
                    $query->whereBetween('sort', [$source->sort, $target->sort])->decrement('sort', 10);
                    $query = Userfolders::where('user_id', $target->user_id)->where('f_id', $target->f_id);
                    $query->where('id', $source_id)->update(['sort' => $target->sort]);
                }
                break;
            default:
                break;
        }
        return $this->response('ok');
    }

    public function postUploadFile(Request $request)
    {
        $user_id = session('token')['user_id'];
        $folder_id = intval($request->input('folder_id'));
        if ($folder_id > 0) {
            $row = Userfolders::where('user_id', $user_id)->find($folder_id);
            if (empty($row)) {
                return $this->error('无效的文件夹');
            }
        }

        if (!$request->hasFile('file')) {
            return $this->error('无效的文件');
        }
        $file = $request->file('file');

        $target_path = 'upload/' . date('Y/m/d/');
        $targetPath = public_path() . '/' . $target_path;
        if (!file_exists($targetPath)) {
            if (!mkdir($targetPath, 0777, 1)) {
                return $this->error('无法建立上传目录');
            }
        }

        $title = $orig_name = safe($request->input('name'));
        $file_type = safe($request->input('type'), 50);
        $file_size = intval($request->input('size'));
        $file_ext = strtolower(getFileExt($title));

        if (!in_array($file_ext, config('extensions.allowExt'))) {
            return $this->error('上传文件的类型不支持');
        }

        $new_filename = uniqid() . '.' . $file_ext;
        $file->move($targetPath, $new_filename);
        $file1 = $target_path . $new_filename;

        $data = compact('user_id', 'folder_id', 'title', 'file1', 'orig_name', 'file_type', 'file_size', 'file_ext');
        $row = new Userfiles;
        foreach ($data as $key => $val) {
            $row->$key = $val;
        }
        if ($row->save()) {
            return $this->response($row);
        }
        return $this->error('文件上传失败');
    }

    public function getDownloadFile(Request $request)
    {
        $user_id = session('token')['user_id'];
        $id = intval($request->input('id'));
        $row = Userfiles::where('user_id', $user_id)->find($id);
        if (empty($row)) {
            return response('Invalid Request.', 404);
        }

        $file = $row->file1;
        if (!file_exists($file)) {
            return response('The file specified does not exist.', 404);
        }

        $file_name = iconv('utf-8', 'gb2312', $row->title);
        $file_size = filesize($file);

        Header('Content-type: application/octet-stream');
        Header('Accept-Ranges: bytes');
        Header('Accept-Length: ' . $file_size);
        Header("Content-Disposition: attachment; filename=" . $file_name);

        $fp = fopen($file, 'r+');
        while (!feof($fp)) {
            $file_data = fread($fp, 1024);
            echo $file_data;
        }
        fclose($fp);
    }

    public function getFileInfo(Request $request)
    {
        $user_id = session('token')['user_id'];
        $id = intval($request->input('id'));

        $row = Userfiles::where('user_id', $user_id)->find($id);
        if (empty($row)) {
            return $this->error('无效的文件');
        }
        $row->file_url = asset($row->file1);
        return $this->response($row);
    }

    public function postRenFile(Request $request)
    {
        $user_id = session('token')['user_id'];

        $id = intval($request->input('id'));
        $row = Userfiles::where('user_id', $user_id)->find($id);
        if (empty($row)) {
            return $this->error('无效的文件');
        }

        $row->title = safe($request->input('title'));
        if ($row->save()) {
            return $this->response($row);
        }
        return $this->error('操作失败');
    }

    public function postMoveFiles(Request $request)
    {
        $user_id = session('token')['user_id'];
        $folder_id = intval($request->input('folder_id'));
        if ($folder_id > 0) {
            $row = Userfolders::where('user_id', $user_id)->find($folder_id);
            if (empty($row)) {
                return $this->error('无效的目标文件夹');
            }
        }

        $ids = explode('|', $request->input('ids'));
        if (empty($ids)) {
            return $this->error('参数错误');
        }
        Userfiles::where('user_id', $user_id)->whereIn('id', $ids)->update(['folder_id' => $folder_id]);
        return $this->response($ids);
    }

    public function postRemoveFiles(Request $request)
    {
        $user_id = session('token')['user_id'];

        $ids = explode('|', $request->input('ids'));
        if (empty($ids)) {
            return $this->error('无效的参数');
        }

        foreach ($ids as $id) {
            $row = Userfiles::where('user_id', $user_id)->find($id);
            if (!empty($row)) {
                $file1 = $row->file1;
                if ($row->delete()) {
                    file_exists($file1) && unlink($file1);
                }
            }
        }
        return $this->response($ids);
    }

}
